             package com.java.diagnostics.visualizer.gc.realtimeV2.parser;
             
             import com.java.diagnostics.visualizer.data.TupleDataBuilder;
             import com.java.diagnostics.visualizer.data.axes.AxisPair;
             import com.java.diagnostics.visualizer.factory.DataFactory;
             import com.java.diagnostics.visualizer.gc.realtime.util.Messages;
             import com.java.diagnostics.visualizer.metadata.TupleMetaData;
             import com.java.diagnostics.visualizer.metadata.TupleMetaData.TableField;
             import com.java.diagnostics.visualizer.metadata.TupleMetaData.TableType;
             import org.xml.sax.Attributes;
             
             public class HeartBeatSummaryParser
               extends GCEventParser
             {
               static final String SUMMARY = "summary";
               public static final String EXCLUSIVE_ACCESS = "exclusiveaccess";
               public static final String GCTHREADPRIORITY = "gcthreadpriority";
               public static final String NONDETERMINISTICSWEEP = "nondeterministicsweep";
               private static final String MINMS = "minms";
               private static final String MAXMS = "maxms";
               private static final String MEANMS = "meanms";
               private static final String QUANTUM = "quantum";
               private static final String MAX = "max";
               private static final String MIN = "min";
               private static final String MINFREE = "minfree";
               private static final String MAXFREE = "maxfree";
               private static final String MEANFREE = "meanfree";
               TupleDataBuilder minPause;
               TupleDataBuilder maxPause;
               TupleDataBuilder meanPause;
               TupleDataBuilder minXAccess;
               TupleDataBuilder maxXAccess;
               TupleDataBuilder meanXAccess;
               private StoredPoints points = new StoredPoints(20);
               
               private final boolean interpolateTimestamps;
               
               long meanPauseMicros;
               
               long quantumCount;
               
               boolean hasImmortal;
               
               HeartBeatSummaryParser(CommonData commonData, DataFactory factory, AxisPair timePair, AxisPair discreteNumberPair, AxisPair discreteTimePair, AxisPair activityPair, boolean interpolateTimestamps)
               {
                 super(commonData);
                 this.interpolateTimestamps = interpolateTimestamps;
                 
                 this.minPause = factory.createTupleData("RealtimeLabels.min.gc.quantum.time", Messages.getString("RealtimeLabels.min.gc.quantum.time"), discreteTimePair);
                 this.maxPause = factory.createTupleData("RealtimeLabels.max.gc.quantum.time", Messages.getString("RealtimeLabels.max.gc.quantum.time"), discreteTimePair);
                 this.meanPause = factory.createTupleData("RealtimeLabels.mean.gc.quantum.time", Messages.getString("RealtimeLabels.mean.gc.quantum.time"), discreteTimePair);
                 this.minXAccess = factory.createTupleData("RealtimeLabels.min.exclusive.access", Messages.getString("RealtimeLabels.min.exclusive.access"), discreteTimePair);
                 this.maxXAccess = factory.createTupleData("RealtimeLabels.max.exclusive.access", Messages.getString("RealtimeLabels.max.exclusive.access"), discreteTimePair);
                 this.meanXAccess = factory.createTupleData("RealtimeLabels.mean.exclusive.access", Messages.getString("RealtimeLabels.mean.exclusive.access"), discreteTimePair);
                 
                 TupleMetaData minPauseMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] {
                   TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 TupleMetaData maxPauseMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] {
                   TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 TupleMetaData meanPauseMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] {
                   TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 TupleMetaData minXAccessMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] {
                   TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 TupleMetaData maxXAccessMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] {
                   TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 TupleMetaData meanXAccessMetaData = new TupleMetaData(
                   TupleMetaData.TableType.ARITHMETIC, new TupleMetaData.TableField[] {
                   TupleMetaData.TableField.MEAN, TupleMetaData.TableField.MIN, TupleMetaData.TableField.MAX });
                 this.minPause.setTupleMetaData(minPauseMetaData);
                 this.maxPause.setTupleMetaData(maxPauseMetaData);
                 this.meanPause.setTupleMetaData(meanPauseMetaData);
                 this.minXAccess.setTupleMetaData(minXAccessMetaData);
                 this.maxXAccess.setTupleMetaData(maxXAccessMetaData);
                 this.meanXAccess.setTupleMetaData(meanXAccessMetaData);
               }
               
               boolean startElement(String uri, String localName, String name, Attributes atts, String comment)
               {
                 boolean ret = true;
                 if (name.equals("quantum")) {
                   double max = CommonData.convertPositiveDouble(atts.getValue("maxms"));
                   if (max >= 0.0D) {
                     this.points.storePoint(this.maxPause, max, comment);
                   }
                   double min = CommonData.convertPositiveDouble(atts.getValue("minms"));
                   if (min >= 0.0D) {
                     this.points.storePoint(this.minPause, min, comment);
                   }
                   double mean = CommonData.convertPositiveDouble(atts.getValue("meanms"));
                   if (mean >= 0.0D) {
                     this.meanPauseMicros = (long) ((mean * 1000.0D));
                     this.points.storePoint(this.meanPause, mean, comment);
                   }
                 } else if (name.equals("exclusiveaccess")) {
                   double max = CommonData.convertPositiveDouble(atts.getValue("maxms"));
                   if (max >= 0.0D) {
                     this.points.storePoint(this.maxXAccess, max, comment);
                   }
                   double min = CommonData.convertPositiveDouble(atts.getValue("minms"));
                   if (min >= 0.0D) {
                     this.points.storePoint(this.minXAccess, min, comment);
                   }
                   double mean = CommonData.convertPositiveDouble(atts.getValue("meanms"));
                   if (mean >= 0.0D) {
                     this.points.storePoint(this.meanXAccess, mean, comment);
                   }
                 } else if (name.equals("classunloading")) {
                   long classesCount = CommonData.getClassesUnloaded(atts);
                   if (classesCount >= 0L) {
                     this.points.storePoint(this.commonData.classesUnloaded, classesCount, comment);
                   }
                   long loaderCount = CommonData.getClassLoadersUnloaded(atts);
                   if (loaderCount >= 0L) {
                     this.points.storePoint(this.commonData.classloadersUnloaded, loaderCount, comment);
                   }
                 } else if (name.equals("refs_cleared")) {
                   long refsCleared = CommonData.getSoftRefsCleared(atts);
                   if (refsCleared >= 0L) {
                     this.points.storePoint(this.commonData.softRefsCleared, refsCleared, comment);
                   }
                   refsCleared = CommonData.getWeakRefsCleared(atts);
                   if (refsCleared >= 0L) {
                     this.points.storePoint(this.commonData.weakRefsCleared, refsCleared, comment);
                   }
                   refsCleared = CommonData.getPhantomRefsCleared(atts);
                   if (refsCleared >= 0L) {
                     this.points.storePoint(this.commonData.phantomRefsCleared, refsCleared, comment);
                   }
                 } else if (name.equals("finalization")) {
                   long finalized = CommonData.getFinalizedCount(atts);
                   if (finalized >= 0L) {
                     this.points.storePoint(this.commonData.objectsQueuedForFinalization, finalized, comment);
                   }
                 } else if (name.equals("warning")) {
                   this.commonData.handleWarning(atts, this.timeMicros / 1000L, comment);
                 } else if (name.equals("nondeterministicsweep")) {
                   this.commonData.handleEvent("non-deterministic sweep", 
                     15, this.timeMicros / 1000L, comment);
                 } else if (name.equals("gcthreadpriority")) {
                   long max = CommonData.convertPositiveInteger(atts.getValue("max"));
                   if (max >= 0L) {
                     this.points.storePoint(this.commonData.maxpriority, max, comment);
                   }
                   long min = CommonData.convertPositiveInteger(atts.getValue("min"));
                   if (min >= 0L) {
                     this.points.storePoint(this.commonData.minpriority, min, comment);
                   }
                 } else {
                   boolean isHeap = name.equals("heap");
                   if ((isHeap) || (name.equals("immortal"))) {
                     this.hasImmortal |= !isHeap;
                     long max = CommonData.convertPositiveInteger(atts.getValue("maxfree"));
                     if (max >= 0L) {
                       TupleDataBuilder data = isHeap ? this.commonData.maxFreeHeap : this.commonData.maxFreeImmortal;
                       this.points.storePoint(data, max, comment);
                     }
                     long min = CommonData.convertPositiveInteger(atts.getValue("minfree"));
                     if (min >= 0L) {
                       TupleDataBuilder data = isHeap ? this.commonData.minFreeHeap : this.commonData.minFreeImmortal;
                       this.points.storePoint(data, min, comment);
                     }
                     long mean = CommonData.convertPositiveInteger(atts.getValue("meanfree"));
                     if (mean >= 0L) {
                       TupleDataBuilder data = isHeap ? this.commonData.meanFreeHeap : this.commonData.meanFreeImmortal;
                       this.points.storePoint(data, mean, comment);
                     }
                   } else {
                     ret = super.startElement(uri, localName, name, atts, comment);
                   }
                 }
                 if (ret) {
                   return true;
                 }
                 complete();
                 return false;
               }
               
               boolean endElement(String uri, String localName, String name, String comment)
               {
                 if ((!name.equals("summary")) && (super.endElement(uri, localName, name, comment))) {
                   return true;
                 }
                 complete();
                 return false;
               }
               
               private void complete()
               {
                 this.commonData.currentGCNumber += 1L;
                 this.commonData.setXAxis(this.timeMicros / 1000.0D);
                 this.points.complete();
               }
               
               void init(long micros, String initialComment, long intervalMicros)
               {
                 this.quantumCount = -1L;
                 this.meanPauseMicros = 0L;
                 super.init(micros, initialComment, intervalMicros);
               }
             }


